﻿#include "netrequest.h"

NetRequest::NetRequest(QObject *parent) : QObject(parent)
{
    m_pNetworkPost = NULL;
    m_pNetworkGet = NULL;
    m_mutexNetGet = NULL;
    m_timer = NULL;
    QDateTime time = QDateTime::currentDateTime();
    QString strfile = QString("./Log/DataMgmtModule%0.txt").arg(time.toString("yyyyMMdd_hhmm"));
    m_file.setFileName(strfile);
}

void NetRequest::doThreadWork(QString task)
{
    if(m_pNetworkPost != NULL){
        if(m_pNetworkPost->networkAccessible() == QNetworkAccessManager::NotAccessible ||
                m_pNetworkPost->networkAccessible() == QNetworkAccessManager::UnknownAccessibility)
        {
            QString strLog = u8"post重设网络可以访问失败，删除并重建QNetworkAccessManager实例";
            m_pNetworkPost->clearAccessCache();
            m_pNetworkPost->deleteLater();
            m_pNetworkPost = NULL;
            if(m_file.open(QIODevice::WriteOnly | QIODevice::Append | QIODevice::Text))
            {
                strLog.append(QDateTime::currentDateTime().toString());
                strLog.append("\t\n");
                m_file.write(strLog.toUtf8());
                m_file.close();
            }
        }
    }
    if(m_pNetworkGet != NULL){
        if(m_pNetworkGet->networkAccessible() == QNetworkAccessManager::NotAccessible ||
                m_pNetworkGet->networkAccessible() == QNetworkAccessManager::UnknownAccessibility)
        {
            QString strLog = u8"get重设网络可以访问失败，删除并重建QNetworkAccessManager实例";
            if(m_file.open(QIODevice::WriteOnly | QIODevice::Append | QIODevice::Text))
            {
                strLog.append(QDateTime::currentDateTime().toString());
                strLog.append("\t\n");
                m_file.write(strLog.toUtf8());
                m_file.close();
            }
            m_pNetworkGet->clearAccessCache();
            m_pNetworkGet->deleteLater();
            m_pNetworkGet = NULL;
            QString strLog2 = u8"get删除并重建QNetworkAccessManager实例后";
            if(m_file.open(QIODevice::WriteOnly | QIODevice::Append | QIODevice::Text))
            {
                strLog2.append(QDateTime::currentDateTime().toString());
                strLog2.append("\t\n");
                m_file.write(strLog2.toUtf8());
                m_file.close();
            }
        }
    }
    if(NULL == m_pNetworkPost){
        m_pNetworkPost = new QNetworkAccessManager();
        connect(m_pNetworkPost,&QNetworkAccessManager::finished,this,&NetRequest::slotRecvNetFinished);
    }
    if(NULL == m_pNetworkGet){
        m_pNetworkGet = new QNetworkAccessManager();
    }
    if(NULL == m_mutexNetGet){
        m_mutexNetGet = new QMutex;
    }
    QJsonParseError error;
    QJsonDocument doc = QJsonDocument::fromJson(task.toUtf8(), &error);
    QJsonObject obj = doc.object();
    QString Cmd = obj.take("Cmd").toString();
    if("queryMenuAll" == Cmd){
        QNetworkRequest request;
        request.setUrl(QUrl(QString("%1/queryMenu?cmd=all").arg(g_Url)));
        QNetworkReply *reply = m_pNetworkGet->get(request);
        replyData *data = new replyData();
        m_mutexNetGet->lock();
        m_mapReply.insert(reply, data);
        m_mutexNetGet->unlock();
        connect(reply,&QNetworkReply::readyRead,this,&NetRequest::slotNetGetReadyRead);
        connect(reply,&QNetworkReply::finished,this,&NetRequest::slotNetGetFinished);
        connect(reply,SIGNAL(error(QNetworkReply::NetworkError)),this,SLOT(slotNetGetError(QNetworkReply::NetworkError)));
    }else if("queryFoodEnergy" == Cmd){
        QNetworkRequest request;
        request.setUrl(QUrl(QString("%1/queryFoodEnergy?name=%2").arg(g_Url).arg(obj.take("name").toString())));
        QNetworkReply *reply = m_pNetworkGet->get(request);
        replyData *data = new replyData();
        m_mutexNetGet->lock();
        m_mapReply.insert(reply, data);
        m_mutexNetGet->unlock();
        connect(reply,&QNetworkReply::readyRead,this,&NetRequest::slotNetGetReadyRead);
        connect(reply,&QNetworkReply::finished,this,&NetRequest::slotNetGetFinished);
        connect(reply,SIGNAL(error(QNetworkReply::NetworkError)),this,SLOT(slotNetGetError(QNetworkReply::NetworkError)));
    }else if("editFoodEnergy" == Cmd){
        QNetworkRequest request;
        request.setUrl(QUrl(QString("%1/editFoodEnergy").arg(g_Url)));
        request.setHeader(QNetworkRequest::ContentTypeHeader,"application/json;charset=UTF-8");
        request.setHeader(QNetworkRequest::ContentLengthHeader,task.toUtf8().size());
        m_pNetworkPost->post(request, task.toUtf8());
    }else if("editFoodInfo" == Cmd){
        QNetworkRequest request;
        request.setUrl(QUrl(QString("%1/editFoodInfo").arg(g_Url)));
        request.setHeader(QNetworkRequest::ContentTypeHeader,"application/json;charset=UTF-8");
        request.setHeader(QNetworkRequest::ContentLengthHeader,task.toUtf8().size());
        m_pNetworkPost->post(request, task.toUtf8());
    }else if("delFoodInfo" == Cmd){
        QNetworkRequest request;
        request.setUrl(QUrl(QString("%1/delFoodInfo?name=%2").arg(g_Url).arg(obj.take("name").toString())));
        QNetworkReply *reply = m_pNetworkGet->get(request);
        replyData *data = new replyData();
        m_mutexNetGet->lock();
        m_mapReply.insert(reply, data);
        m_mutexNetGet->unlock();
        connect(reply,&QNetworkReply::readyRead,this,&NetRequest::slotNetGetReadyRead);
        connect(reply,&QNetworkReply::finished,this,&NetRequest::slotNetGetFinished);
        connect(reply,SIGNAL(error(QNetworkReply::NetworkError)),this,SLOT(slotNetGetError(QNetworkReply::NetworkError)));
    }else if("queryFoodInfo" == Cmd){
        QNetworkRequest request;
        request.setUrl(QUrl(QString("%1/queryFoodInfo?name=%2").arg(g_Url).arg(obj.take("name").toString())));
        QNetworkReply *reply = m_pNetworkGet->get(request);
        replyData *data = new replyData();
        m_mutexNetGet->lock();
        m_mapReply.insert(reply, data);
        m_mutexNetGet->unlock();
        connect(reply,&QNetworkReply::readyRead,this,&NetRequest::slotNetGetReadyRead);
        connect(reply,&QNetworkReply::finished,this,&NetRequest::slotNetGetFinished);
        connect(reply,SIGNAL(error(QNetworkReply::NetworkError)),this,SLOT(slotNetGetError(QNetworkReply::NetworkError)));
    }else if("delFixFoodFea" == Cmd){
        QNetworkRequest request;
        request.setUrl(QUrl(QString("%1/delFixFoodFea").arg(g_Url)));
        request.setHeader(QNetworkRequest::ContentTypeHeader,"application/json;charset=UTF-8");
        request.setHeader(QNetworkRequest::ContentLengthHeader,task.toUtf8().size());
        m_pNetworkPost->post(request, task.toUtf8());
    }else if("queryAllMenus" == Cmd){
        QNetworkRequest request;
        request.setUrl(QUrl(QString("%1/queryAllMenus").arg(g_Url)));
        QNetworkReply *reply = m_pNetworkGet->get(request);
        replyData *data = new replyData();
        m_mutexNetGet->lock();
        m_mapReply.insert(reply, data);
        m_mutexNetGet->unlock();
        connect(reply,&QNetworkReply::readyRead,this,&NetRequest::slotNetGetReadyRead);
        connect(reply,&QNetworkReply::finished,this,&NetRequest::slotNetGetFinished);
        connect(reply,SIGNAL(error(QNetworkReply::NetworkError)),this,SLOT(slotNetGetError(QNetworkReply::NetworkError)));
    }else if("queryMenuInfo" == Cmd){
        QNetworkRequest request;
        request.setUrl(QUrl(QString("%1/queryMenuInfo?name=%2").arg(g_Url).arg(obj.take("MenuName").toString())));
        QNetworkReply *reply = m_pNetworkGet->get(request);
        replyData *data = new replyData();
        m_mutexNetGet->lock();
        m_mapReply.insert(reply, data);
        m_mutexNetGet->unlock();
        connect(reply,&QNetworkReply::readyRead,this,&NetRequest::slotNetGetReadyRead);
        connect(reply,&QNetworkReply::finished,this,&NetRequest::slotNetGetFinished);
        connect(reply,SIGNAL(error(QNetworkReply::NetworkError)),this,SLOT(slotNetGetError(QNetworkReply::NetworkError)));
    }else if("setCurrentMenu" == Cmd){
        QNetworkRequest request;
        request.setUrl(QUrl(QString("%1/setCurrentMenu?name=%2").arg(g_Url).arg(obj.take("MenuName").toString())));
        QNetworkReply *reply = m_pNetworkGet->get(request);
        replyData *data = new replyData();
        m_mutexNetGet->lock();
        m_mapReply.insert(reply, data);
        m_mutexNetGet->unlock();
        connect(reply,&QNetworkReply::readyRead,this,&NetRequest::slotNetGetReadyRead);
        connect(reply,&QNetworkReply::finished,this,&NetRequest::slotNetGetFinished);
        connect(reply,SIGNAL(error(QNetworkReply::NetworkError)),this,SLOT(slotNetGetError(QNetworkReply::NetworkError)));
    }else if("delMeun" == Cmd){
        QNetworkRequest request;
        request.setUrl(QUrl(QString("%1/delMeun?name=%2").arg(g_Url).arg(obj.take("MenuName").toString())));
        QNetworkReply *reply = m_pNetworkGet->get(request);
        replyData *data = new replyData();
        m_mutexNetGet->lock();
        m_mapReply.insert(reply, data);
        m_mutexNetGet->unlock();
        connect(reply,&QNetworkReply::readyRead,this,&NetRequest::slotNetGetReadyRead);
        connect(reply,&QNetworkReply::finished,this,&NetRequest::slotNetGetFinished);
        connect(reply,SIGNAL(error(QNetworkReply::NetworkError)),this,SLOT(slotNetGetError(QNetworkReply::NetworkError)));
    }else if("editMenuContent" == Cmd){
        QNetworkRequest request;
        request.setUrl(QUrl(QString("%1/editMenuContent").arg(g_Url)));
        request.setHeader(QNetworkRequest::ContentTypeHeader,"application/json;charset=UTF-8");
        request.setHeader(QNetworkRequest::ContentLengthHeader,task.toUtf8().size());
        m_pNetworkPost->post(request, task.toUtf8());
    }else if("bill_query" == Cmd){
        QNetworkRequest request;
        request.setUrl(QUrl(QString("%1/bill_query?start=%2&end=%3&paytype=%4&from=%5&count=%6")
                            .arg(g_Url)
                            .arg(obj.take("start_time").toInt())
                            .arg(obj.take("end_time").toInt())
                            .arg(obj.take("pay_type").toInt())
                            .arg(obj.take("from").toInt())
                            .arg(obj.take("count").toInt())));
        QNetworkReply *reply = m_pNetworkGet->get(request);
        replyData *data = new replyData();
        m_mutexNetGet->lock();
        m_mapReply.insert(reply, data);
        m_mutexNetGet->unlock();
        connect(reply,&QNetworkReply::readyRead,this,&NetRequest::slotNetGetReadyRead);
        connect(reply,&QNetworkReply::finished,this,&NetRequest::slotNetGetFinished);
        connect(reply,SIGNAL(error(QNetworkReply::NetworkError)),this,SLOT(slotNetGetError(QNetworkReply::NetworkError)));
    }else if("bill_countmoney" == Cmd){
        QNetworkRequest request;
        request.setUrl(QUrl(QString("%1/bill_countmoney?start=%2&end=%3")
                            .arg(g_Url)
                            .arg(obj.take("start_time").toInt())
                            .arg(obj.take("end_time").toInt())));
        QNetworkReply *reply = m_pNetworkGet->get(request);
        replyData *data = new replyData();
        m_mutexNetGet->lock();
        m_mapReply.insert(reply, data);
        m_mutexNetGet->unlock();
        connect(reply,&QNetworkReply::readyRead,this,&NetRequest::slotNetGetReadyRead);
        connect(reply,&QNetworkReply::finished,this,&NetRequest::slotNetGetFinished);
        connect(reply,SIGNAL(error(QNetworkReply::NetworkError)),this,SLOT(slotNetGetError(QNetworkReply::NetworkError)));
    }else if("bill_detail" == Cmd){
        QNetworkRequest request;
        request.setUrl(QUrl(QString("%1/bill_detail?bill_id=%2")
                            .arg(g_Url)
                            .arg(obj.take("bill_id").toString())));
        QNetworkReply *reply = m_pNetworkGet->get(request);
        replyData *data = new replyData();
        m_mutexNetGet->lock();
        m_mapReply.insert(reply, data);
        m_mutexNetGet->unlock();
        connect(reply,&QNetworkReply::readyRead,this,&NetRequest::slotNetGetReadyRead);
        connect(reply,&QNetworkReply::finished,this,&NetRequest::slotNetGetFinished);
        connect(reply,SIGNAL(error(QNetworkReply::NetworkError)),this,SLOT(slotNetGetError(QNetworkReply::NetworkError)));
    }else if("action_query" == Cmd){
        QNetworkRequest request;
        request.setUrl(QUrl(QString("%1/action_query?start=%2&end=%3&from=%4&count=%5")
                            .arg(g_Url)
                            .arg(obj.take("start_time").toInt())
                            .arg(obj.take("end_time").toInt())
                            .arg(obj.take("from").toInt())
                            .arg(obj.take("count").toInt())
                            ));
        QNetworkReply *reply = m_pNetworkGet->get(request);
        replyData *data = new replyData();
        m_mutexNetGet->lock();
        m_mapReply.insert(reply, data);
        m_mutexNetGet->unlock();
        connect(reply,&QNetworkReply::readyRead,this,&NetRequest::slotNetGetReadyRead);
        connect(reply,&QNetworkReply::finished,this,&NetRequest::slotNetGetFinished);
        connect(reply,SIGNAL(error(QNetworkReply::NetworkError)),this,SLOT(slotNetGetError(QNetworkReply::NetworkError)));
    }else if("action_record_query" == Cmd){
        QNetworkRequest request;
        request.setUrl(QUrl(QString("%1/action_record_query?start=%2&end=%3")
                            .arg(g_Url).arg(obj.take("start_time").toInt())
                            .arg(obj.take("end_time").toInt())
                            ));
        qDebug() << "action_record_query=" << request.url();
        QNetworkReply *reply = m_pNetworkGet->get(request);
        replyData *data = new replyData();
        m_mutexNetGet->lock();
        m_mapReply.insert(reply, data);
        m_mutexNetGet->unlock();
        connect(reply,&QNetworkReply::readyRead,this,&NetRequest::slotNetGetReadyRead);
        connect(reply,&QNetworkReply::finished,this,&NetRequest::slotNetGetFinished);
        connect(reply,SIGNAL(error(QNetworkReply::NetworkError)),this,SLOT(slotNetGetError(QNetworkReply::NetworkError)));
    }else if("report_imageUpload" == Cmd){
        QNetworkRequest request;
        request.setUrl(QUrl(QString("%1/report_imageUpload").arg(g_Url)));
        request.setHeader(QNetworkRequest::ContentTypeHeader,"application/json;charset=UTF-8");
        request.setHeader(QNetworkRequest::ContentLengthHeader,task.toUtf8().size());
        m_pNetworkPost->post(request, task.toUtf8());
    }
}

void NetRequest::slotRecvNetFinished(QNetworkReply *reply)
{
    QNetworkReply::NetworkError err = reply->error();
    if(QNetworkReply::NoError == err) {
        if(reply->bytesAvailable() > 0) {
            QByteArray data = reply->readAll();
            emit SendReplyMessage(QString(data));
        }
    }
    else
    {
        m_pNetworkPost->setNetworkAccessible(QNetworkAccessManager::Accessible);
    }
    reply->close();
    reply->deleteLater();
    reply = NULL;
}

void NetRequest::slotNetGetReadyRead()
{
    QNetworkReply *reply = (QNetworkReply*)sender();
    if(NULL == reply) {
        QString szLog = "NetRequest::slotNetGetReadyRead():reply=null";
        qDebug() << szLog.toUtf8().data();
        return;
    }
    if(QNetworkReply::NoError == reply->error()){
        if(reply->bytesAvailable() > 0){
            replyData *repata = NULL;
            m_mutexNetGet->lock();
            QMap<QNetworkReply*, replyData*>::const_iterator i = m_mapReply.find(reply);
            if (i != m_mapReply.end() && i.key() == reply){
                repata = i.value();
            }
            m_mutexNetGet->unlock();
            if(NULL != repata){
                repata->data += reply->readAll();
            }
        }
    } else {
        QVariant status_code = reply->attribute(QNetworkRequest::HttpStatusCodeAttribute);
        QString szLog = QString("NetRequest::slotNetGetReadyRead() HttpStatusError=%1,qtReplyError=%2,desc=%3")
                .arg(status_code.toInt())
                .arg(reply->error())
                .arg(reply->errorString());
        qDebug() << szLog.toUtf8().data();
    }
//    qDebug() << "readyread thread id=" << QThread::currentThreadId();
}

void NetRequest::slotNetGetFinished()
{
    QNetworkReply *reply = (QNetworkReply*)sender();
    if(NULL == reply) {
        return;
    }
    replyData *repata = NULL;
    m_mutexNetGet->lock();
    QMap<QNetworkReply*, replyData*>::const_iterator i = m_mapReply.find(reply);
    if (i != m_mapReply.end() && i.key() == reply){
        repata = i.value();
    }
    m_mutexNetGet->unlock();
    if(QNetworkReply::NoError == reply->error()){
        if(NULL != repata){
            //处理 repata->data
            emit SendReplyMessage(QString(repata->data));
        }
    }else{
        m_pNetworkGet->setNetworkAccessible(QNetworkAccessManager::Accessible);
    }
    if(NULL != repata){
        delete repata;
        repata = NULL;
        m_mutexNetGet->lock();
        m_mapReply.remove(reply);
        m_mutexNetGet->unlock();
    }
    reply->close();
    reply->deleteLater();
    reply = NULL;
}

void NetRequest::slotNetGetError(QNetworkReply::NetworkError error)
{
    QNetworkReply *reply = (QNetworkReply*)sender();
    QVariant status_code = reply->attribute(QNetworkRequest::HttpStatusCodeAttribute);
    QString szLog = QString("CTmNetComm::slotNetGetError,HttpError=%1,paramError=%2,qtError=%3,read=%4")
            .arg(status_code.toInt())
            .arg(error)
            .arg(reply->error())
            .arg(reply->errorString());
    m_pNetworkGet->setNetworkAccessible(QNetworkAccessManager::Accessible);
    if(m_file.open(QIODevice::WriteOnly | QIODevice::Append | QIODevice::Text))
    {
        szLog.append(QDateTime::currentDateTime().toString());
        m_file.write(szLog.toUtf8());
        m_file.write("\t\n");
        m_file.flush();
        m_file.close();
    }
}
